﻿using System;                                                     
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpBits.Base;
using VMDS.Business.Entities;

namespace VMDS.Business.Processes
{
    public class BitsServiceArgs:EventArgs
    {
        public Guid JobId{get;set;}
        public int JobProgress{get;set;}
    }

    public static class BitsService
    {
        static BitsManager bitsManager;
        public static event EventHandler<BitsServiceArgs> OnJobModified;
        static BitsService()
        {
            bitsManager = new BitsManager();
            InvokeJobs();
        }
        static void InvokeJobs()
        {
            foreach (var bitsJob in
                bitsManager.Jobs.Select(job => job.Value).TakeWhile(bitsJob => (bitsJob.DisplayName == "VMDS_VM") || (bitsJob.DisplayName == "VMDS_OS")))
            {
                bitsJob.OnJobModified += new EventHandler<JobNotificationEventArgs>(bitsJob_OnJobModified);
                bitsJob.OnJobTransferred += new EventHandler<JobNotificationEventArgs>(bitsJob_OnJobTransferred);
            }
        }

        static void InvokeOnJobModified(BitsServiceArgs e)
        {
            EventHandler<BitsServiceArgs> handler = OnJobModified;
            if (handler != null) handler(null, e);
        }

        public static event EventHandler<BitsServiceArgs> OnJobTransferred;

        static void InvokeOnJobTransferred(BitsServiceArgs e)
        {
            EventHandler<BitsServiceArgs> handler = OnJobTransferred;
            if (handler != null) handler(null, e);
        }

        public static List<Guid> JobCodes
        {
          get
          {
             
              List<Guid> Jobs = new List<Guid>();
              foreach (KeyValuePair<Guid, BitsJob> pair in bitsManager.Jobs)
              {
                  if (pair.Value.DisplayName=="VMDS")
                  Jobs.Add(pair.Key);
              }
              return Jobs;
          }  
        }

        public static bool IsInBITS(VM vm)
        {
            return
                (bitsManager.Jobs.Select(job => job.Value).Where(j => j != null).Any(
                    j => (j.DisplayName == "VMDS_VM") && (j.Description == vm.Id.ToString())));
        }
        public static bool IsInBITS(OS os)
        {
            return
                (bitsManager.Jobs.Select(job => job.Value).Where(j => j != null).Any(
                    j => (j.DisplayName == "VMDS_OS") && (j.Description == os.Id.ToString())));
        }
        public static Guid Download(OS os, string fromDir, string toDir)
        {
           return NewJob(fromDir, toDir, "VMDS_OS", os.Id.ToString());
        }
        public static Guid Download(VM vm, string fromDir, string toDir)
        {
           return NewJob(fromDir, toDir, "VMDS_VM", vm.Id.ToString());
        }
      

        static Guid NewJob(string from, string to, string name, string description)
        {
            var bitsJob = bitsManager.CreateJob(name, JobType.Download);
            bitsJob.Priority = JobPriority.Normal;
            bitsJob.Description = description;
            var cache = to + "\\" + bitsJob.JobId;
            Directory.CreateDirectory(cache);
           
            foreach (string file in Directory.EnumerateFiles(from))
            {
                var local = cache+"\\"+(new FileInfo(file).Name);
                bitsJob.AddFile(file, local);
            }
            bitsJob.Resume();
            return bitsJob.JobId;
        }

        public static BitsJob GetJob(Guid id)
        {
            return bitsManager.Jobs.Where(pair => pair.Key == id).Select(pair => pair.Value).FirstOrDefault();
        }

        static void  bitsJob_OnJobTransferred(object sender, JobNotificationEventArgs e)
        {
            GetJob(e.From).Complete();
            MessageBox.Show("transferred");
        }

        private static bool _visible;
        static void  bitsJob_OnJobModified(object sender, JobNotificationEventArgs e)
        {
            var bitsJob = GetJob(e.From);
            if (bitsJob == null) return;
            int a = int.Parse((bitsJob.Progress.BytesTransferred / 1024).ToString());
            int b = int.Parse((bitsJob.Progress.BytesTotal / 1024).ToString());
            int p = Convert.ToInt32(100 * (a / (float)b));
            InvokeOnJobModified(new BitsServiceArgs() {JobId = e.From, JobProgress = p});
        }

    }
}
